package com.flywen.generator;

import com.flywen.generator.common.DBName;

/**
 * @Author
 * @Create 2019-01-24 13:53
 * @Version 1.0
 * @Description
 */
public class Field {

    private String fieldName;
    private String fieldType;
    private String fieldTypeXml;
    private String propertyName;
    private String description;
    private boolean isKey;
    private final int precision;
    private int scale=0;
    private String javaTypeName;
    private String gmethodName;
    private String smethodName;
    private String condition;

    public String getJdbcType(String javaType) {
        if (DBName.MYSQL.equals(Generator.dbName)){
            if (javaType.equals("VARCHAR")) {
                return "VARCHAR";
            } else if (javaType.equals("LONG")) {
                return "LONGVARCHAR";
            } else if (javaType.equals("NUMBER")) {
                return "NUMERIC";
            } else if (javaType.equals("DATE")) {
                return "TIMESTAMP";
            } else if (javaType.equals("TIMESTAMP")) {
                return "TIMESTAMP";
            } else if (javaType.equals("DATETIME")) {
                return "TIMESTAMP";
            } else if (javaType.equals("CHAR")) {
                return "CHAR";
            } else if (javaType.equals("CLOB")) {
                return "CLOB";
            } else if (javaType.equals("TEXT")) {
                return "CLOB";
            } else if (javaType.equals("DECIMAL")) {
                return "DECIMAL";
            } else if (javaType.equals("DOUBLE")) {
                return "DOUBLE";
            } else if (javaType.equals("INT")) {
                return "INTEGER";
            } else if (javaType.equals("FLOAT")) {
                return "FLOAT";
            } else if (javaType.equals("BLOB")) {
                return "BLOB";
            } else if (javaType.equals("BIGINT")) {
                return "BIGINT";
            } else if (javaType.equals("TINYINT")) {
                return "INTEGER";
            } else if (javaType.equals("BIT")) {
                return "BIT";
            } else if (javaType.equals("SMALLINT")) {
                return "SMALLINT";
            } else {
                throw new RuntimeException("please implenents java type: " + javaType + "'s java type mapping!");
            }
        }else if (DBName.ORACLE.equals(Generator.dbName)){
            if (javaType.equals("VARCHAR")) {
                return "VARCHAR";
            }else if (javaType.equals("VARCHAR2")) {
                return "VARCHAR";
            } else if (javaType.equals("LONG")) {
                return "LONGVARCHAR";
            } else if (javaType.equals("NUMBER")) {
                if (this.scale > 0) {
                    return "DECIMAL";
                } else if (this.precision == 1) {
                    return "Boolean";
                } else {
                    return (this.precision > 10 || 0 == this.precision) ? "BIGINT" : "INTEGER";
                }
            } else if (javaType.equals("NUMERIC")) {

                if (this.scale > 0) {
                    return "DECIMAL";
                } else if (this.precision == 1) {
                    return "Boolean";
                } else {
                    return (this.precision > 10 || 0 == this.precision) ? "BIGINT" : "INTEGER";
                }
            } else if (javaType.equals("DATE")) {
                return "TIMESTAMP";
            } else if (javaType.equals("TIMESTAMP")) {
                return "TIMESTAMP";
            } else if (javaType.equals("DATETIME")) {
                return "TIMESTAMP";
            } else if (javaType.equals("CHAR")) {
                return "CHAR";
            } else if (javaType.equals("CLOB")) {
                return "CLOB";
            } else if (javaType.equals("TEXT")) {
                return "CLOB";
            } else if (javaType.equals("DECIMAL")) {
                return "DECIMAL";
            } else if (javaType.equals("DOUBLE")) {
                return "DOUBLE";
            } else if (javaType.equals("INT")) {
                return "INTEGER";
            } else if (javaType.equals("FLOAT")) {
                return "FLOAT";
            } else if (javaType.equals("BLOB")) {
                return "BLOB";
            } else if (javaType.equals("CLOB")) {
                return "CLOB";
            } else if (javaType.equals("BIGINT")) {
                return "BIGINT";
            } else if (javaType.equals("TINYINT")) {
                return "INTEGER";
            } else if (javaType.equals("BIT")) {
                return "BIT";
            } else if (javaType.equals("SMALLINT")) {
                return "SMALLINT";
            } else {
                throw new RuntimeException("please implenents java type: " + javaType + "'s java type mapping!");
            }
        }else{
            throw new UnsupportedOperationException("暂不支持类型 db: "+Generator.dbName);
        }

    }

    public Field(String fieldName, String fieldType, String propertyName, boolean isKey, int precision, int scale) {
        this.fieldName = fieldName.toLowerCase();
        this.fieldType = fieldType;
        this.precision = precision;
        this.isKey = isKey;
        this.scale = scale;
        this.propertyName = propertyName;
        this.fieldTypeXml = this.getJdbcType(fieldType);
        this.smethodName = "set" + this.propertyName.substring(0, 1).toUpperCase() + this.propertyName.substring(1);
        this.gmethodName = "get" + this.propertyName.substring(0, 1).toUpperCase() + this.propertyName.substring(1);
        this.javaTypeName = this.getJavaType();
        this.condition = this.genCon();
        System.out.println(this.condition);
    }

    public String getDescription() {
        return this.description == null ? "" : this.description;
    }

    public String getFieldName() {
        return this.fieldName;
    }

    public String getFieldType() {
        return this.fieldType;
    }

    public String getJavaType() {
        if (this.fieldType.toUpperCase().startsWith("VARCHAR")) {
            return "String";
        } else if (this.fieldType.toUpperCase().startsWith("CHAR")) {
            return "String";
        } else if (this.fieldType.toUpperCase().startsWith("TEXT")) {
            return "String";
        } else if (this.fieldType.toUpperCase().startsWith("DATE")) {
            return "Date";
        } else if (this.fieldType.toUpperCase().startsWith("DECIMAL")) {
            return "BigDecimal";
        } else if (this.fieldType.toUpperCase().startsWith("DOUBLE")) {
            return "BigDecimal";
        } else if (this.fieldType.toUpperCase().startsWith("FLOAT")) {
            return "BigDecimal";
        } else if (this.fieldType.toUpperCase().startsWith("INT")) {
            return "Integer";
        } else if (this.fieldType.toUpperCase().startsWith("TINYINT")) {
            return "Integer";
        } else if (this.fieldType.toUpperCase().startsWith("INTEGER")) {
            return "Integer";
        } else if (this.fieldType.toUpperCase().startsWith("NUMBER")) {
            if (this.scale > 0) {
                return "BigDecimal";
            } else if (this.precision == 1) {
                return "Boolean";
            } else {
                return (this.precision > 10 || 0 == this.precision) ? "Long" : "Integer";
            }
        } else if (this.fieldType.toUpperCase().startsWith("NUMERIC")) {
            if (this.scale > 0) {
                return "BigDecimal";
            } else if (this.precision == 1) {
                return "Boolean";
            } else {
                return (this.precision > 10 || 0 == this.precision) ? "Long" : "Integer";
            }
        } else if (this.fieldType.toUpperCase().startsWith("TIMESTAMP")) {
            return "Timestamp";
        } else if (this.fieldType.toUpperCase().startsWith("LONG")) {
            return "String";
        } else if (this.fieldType.toUpperCase().startsWith("BLOB")) {
            return "String";
        } else if (this.fieldType.toUpperCase().startsWith("CLOB")) {
            return "String";
        } else if (this.fieldType.toUpperCase().startsWith("BIGINT")) {
            return "Long";
        } else if (this.fieldType.toUpperCase().startsWith("BIT")) {
            return "Boolean";
        } else if (this.fieldType.toUpperCase().startsWith("SMALLINT")) {
            return "Integer";
        } else {
            throw new RuntimeException("please implenents jdbc type: " + this.fieldType + "'s java type mapping!");
        }
    }

    public String getPropertyName() {
        return this.propertyName;
    }

    public int getScale() {
        return this.scale;
    }

    public boolean isKey() {
        return this.isKey;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public void setFieldType(String fieldType) {
        this.fieldType = fieldType;
    }

    public void setKey(boolean isKey) {
        this.isKey = isKey;
    }

    public void setPropertyName(String propertyName) {
        this.propertyName = propertyName;
    }

    public void setScale(int scale) {
        this.scale = scale;
    }

    public String toString() {
        return this.fieldName + "(Key:" + this.isKey + ")" + "_" + this.fieldType + "_" + this.propertyName;
    }

    public String getCondition() {
        return this.condition;
    }

    private String genCon() {
        return this.javaTypeName.equals("String") ? this.propertyName + " != null and  " + this.propertyName + " != ''  " : this.propertyName + " != null  ";
    }

    public String getJavaTypeName() {
        return this.javaTypeName;
    }

    public void setJavaTypeName(String javaTypeName) {
        this.javaTypeName = javaTypeName;
    }

    public String getGmethodName() {
        return this.gmethodName == null ? "" : this.gmethodName;
    }

    public void setGmethodName(String gmethodName) {
        this.gmethodName = gmethodName;
    }

    public String getSmethodName() {
        return this.smethodName;
    }

    public void setSmethodName(String smethodName) {
        this.smethodName = smethodName;
    }

    public String getFieldTypeXml() {
        return this.fieldTypeXml;
    }

    public void setFieldTypeXml(String fieldTypeXml) {
        this.fieldTypeXml = fieldTypeXml;
    }

    public int getPrecision() {
        return this.precision;
    }

}
